具体代码请看:JavaJniTest项目的datastructure33hashmap
常见面试题:
- equals 和 == 的区别,hashCode 与它们之间的联系?
- HashMap 的长度为什么是 2 的幂次?
- 五个线程同时往 HashMap 中 put 数据会发生什么?
- ConcurrentHashMap 是怎么保证线程安全的?
- HashMap在jdk1.8之后为何引入了红黑树
1. HashMap默认的一些参数:
- HashMap
数组长度默认大小:16、默认阈值:12、加载因子:0.75f,扩容为当前数组长度大小的一倍 - vector :没指定大小的情况下,初始大小为
10,扩容为当前大小的一倍 - ArrayList : 没指定大小的情况下,初始大小为
10,扩容为当前大小的二分之一
为什么加载因子是 0.75
加载因子越大,填满的元素越多,空间利用率越高,但发生冲突的机会变大了;
加载因子越小,填满的元素越少,冲突发生的机会减小,但空间浪费了更多了,而且还会提高扩容rehash操作的次数。
2. == 和 equals
== 判断的是地址
equals 也是判断两个对象相等,但是更多的是判断内容相等,多用于集合判断
3. hashCode:
如果你复写了 equals 一般要复写 hashCode,一般集合中都是通过hashcode去减少时间复杂度,获取的时候也会判断hashcode是否相等
hashcode = 地址值 >> 16
总结:
- hash 值相等两个对象不一定相等
- 两个对象不相等 hash 值有可能相等
- hash 值不相等的两个对象,这两个对象肯定不相等
4. HashMap 的长度为什么是 2 的幂次?
为了能让HashMap存取高效,尽量减少碰撞,也就是要尽量把数据分配均匀,Hash值的范围是-2147483648到2147483647,前后加起来有40亿的映射空间。
这个散列值是不能直接拿来用的。用之前需要先对数组长度取模运算,得到的才是在数组中存储的位置。
总结:hash%length=hash&(length-1),但前提是length是2的n次方,并且采用&运算比%运算效率高,且为了减少碰撞,分配均匀,所以长度才会是 2的幂次。
举例:
例如长度为9时候,3&(9-1)=0 2&(9-1)=0 ,都在0上,碰撞了;
例如长度为8时候,3&(8-1)=3 2&(8-1)=2 ,不同位置上,不碰撞;
5. 手写HashMap时关键代码分析:
1 | /** |